﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using UnityEngine;

public static class SavWav
{
    private const int HEADER_SIZE = 0x2c;

    private static void ConvertAndWrite(FileStream fileStream, AudioClip clip)
    {
        float[] data = new float[clip.samples];
        clip.GetData(data, 0);
        short[] numArray2 = new short[data.Length];
        byte[] array = new byte[data.Length * 2];
        int num = 0x7fff;
        for (int i = 0; i < data.Length; i++)
        {
            numArray2[i] = (short) (data[i] * num);
            byte[] buffer2 = new byte[2];
            BitConverter.GetBytes(numArray2[i]).CopyTo(array, (int) (i * 2));
        }
        fileStream.Write(array, 0, array.Length);
    }

    private static FileStream CreateEmpty(string filepath)
    {
        FileStream stream = new FileStream(filepath, FileMode.Create);
        byte num = 0;
        for (int i = 0; i < 0x2c; i++)
        {
            stream.WriteByte(num);
        }
        return stream;
    }

    public static bool Save(this AudioClip clip, string filepath)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(filepath));
        using (FileStream stream = CreateEmpty(filepath))
        {
            ConvertAndWrite(stream, clip);
            WriteHeader(stream, clip);
        }
        return true;
    }

    public static bool SaveToPersistentDataPath(this AudioClip clip, string filename)
    {
        if (!filename.ToLower().EndsWith(".wav"))
        {
            filename = filename + ".wav";
        }
        string filepath = Path.Combine(Application.persistentDataPath, filename);
        return clip.Save(filepath);
    }

    public static AudioClip TrimSilence(this AudioClip clip, float min)
    {
        float[] data = new float[clip.samples];
        clip.GetData(data, 0);
        return TrimSilence(new List<float>(data), min, clip.channels, clip.frequency);
    }

    public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz)
    {
        return TrimSilence(samples, min, channels, hz, false);
    }

    public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz, bool stream)
    {
        int count = 0;
        while (count < samples.Count)
        {
            if (Mathf.Abs(samples[count]) > min)
            {
                break;
            }
            count++;
        }
        samples.RemoveRange(0, count);
        count = samples.Count - 1;
        while (count > 0)
        {
            if (Mathf.Abs(samples[count]) > min)
            {
                break;
            }
            count--;
        }
        samples.RemoveRange(count, samples.Count - count);
        AudioClip clip = AudioClip.Create("TempClip", samples.Count, channels, hz, stream);
        clip.SetData(samples.ToArray(), 0);
        return clip;
    }

    private static void WriteHeader(FileStream fileStream, AudioClip clip)
    {
        int frequency = clip.frequency;
        int channels = clip.channels;
        int samples = clip.samples;
        fileStream.Seek(0L, SeekOrigin.Begin);
        byte[] bytes = Encoding.UTF8.GetBytes("RIFF");
        fileStream.Write(bytes, 0, 4);
        byte[] array = BitConverter.GetBytes((long) (fileStream.Length - 8L));
        fileStream.Write(array, 0, 4);
        byte[] buffer3 = Encoding.UTF8.GetBytes("WAVE");
        fileStream.Write(buffer3, 0, 4);
        byte[] buffer4 = Encoding.UTF8.GetBytes("fmt ");
        fileStream.Write(buffer4, 0, 4);
        byte[] buffer5 = BitConverter.GetBytes(0x10);
        fileStream.Write(buffer5, 0, 4);
        ushort num4 = 1;
        byte[] buffer6 = BitConverter.GetBytes(num4);
        fileStream.Write(buffer6, 0, 2);
        byte[] buffer7 = BitConverter.GetBytes(channels);
        fileStream.Write(buffer7, 0, 2);
        byte[] buffer8 = BitConverter.GetBytes(frequency);
        fileStream.Write(buffer8, 0, 4);
        byte[] buffer9 = BitConverter.GetBytes((int) ((frequency * channels) * 2));
        fileStream.Write(buffer9, 0, 4);
        ushort num5 = (ushort) (channels * 2);
        fileStream.Write(BitConverter.GetBytes(num5), 0, 2);
        ushort num6 = 0x10;
        byte[] buffer10 = BitConverter.GetBytes(num6);
        fileStream.Write(buffer10, 0, 2);
        byte[] buffer11 = Encoding.UTF8.GetBytes("data");
        fileStream.Write(buffer11, 0, 4);
        byte[] buffer12 = BitConverter.GetBytes((int) ((samples * channels) * 2));
        fileStream.Write(buffer12, 0, 4);
    }
}

